home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i051: Screen-oriented rolodex program, Part03/04
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Dave Ihnat <ihnp4!homebru!ignatz>
- Posting-number: Volume 13, Issue 51
- Archive-name: rolodex/part03
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 4)."
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f './io.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./io.c'\"
- else
- echo shar: Extracting \"'./io.c'\" \(10740 characters\)
- sed "s/^X//" >'./io.c' <<'END_OF_FILE'
- X/* io.c */
- X#include <stdio.h>
- X#ifdef UNIX
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#ifdef BSD
- X#include <sys/file.h>
- X#else
- X#include <fcntl.h>
- X#endif
- X#endif
- X
- X#ifdef VMS
- X#include <types.h>
- X#include <stat.h>
- X#include <file.h>
- X#endif
- X
- X#ifdef MSDOS
- X# ifdef MSC
- X# include <sys/types.h>
- X# endif /* MSC */
- X#include <sys/stat.h>
- X#include <fcntl.h>
- X#endif
- X
- X#include <ctype.h>
- X
- X#ifdef TMC
- X#include <ctools.h>
- X#else
- X#include "ctools.h"
- X#endif
- X
- X#include "rolofilz.h"
- X#include "datadef.h"
- X
- X
- Xchar *Field_Names[N_BASIC_FIELDS] = {
- X
- X "Name: ", "Work Phone: ", "Home Phone: ", "Company: ",
- X "Work Address: ", "Home Address: ", "Remarks: ", "Date Updated: "
- X
- X };
- X
- XPtr_Rolo_List Begin_Rlist = 0;
- XPtr_Rolo_List End_Rlist = 0;
- XPtr_Rolo_List Current_Entry = 0;
- X
- Xstatic char *rolofiledata;
- X
- X/*
- X * The following has been added to accomplish two goals:
- X *
- X * 1) Document all help files expected in the system, to avoid/identify
- X * lost elements in distribution.
- X *
- X * 2) Allow a flexible, easily-modified way of changing filenames as
- X * necessary/desired to comply with different operating systems.
- X */
- Xchar *hlpfiles[] = {
- X "addhelp.hlp", /* ADDHELP */
- X "addinfo.hlp", /* ADDINFO */
- X "confirm.hlp", /* CONFIRMHELP */
- X "entrymnu.hlp", /* ENTRYMENU */
- X "escan.hlp", /* ESCANHELP */
- X "esearch.hlp", /* ESEARCHHELP */
- X "fldsrch.hlp", /* FIELDSEARCHHELP */
- X#ifdef UNIX
- X "lockinfo.unx", /* LOCKINFO */
- X#endif
- X#ifdef VMS
- X "lockinfo.vms", /* LOCKINFO */
- X#endif
- X#ifdef MSDOS
- X "lockinfo.dos", /* LOCKINFO */
- X#endif
- X "mainmenu.hlp", /* MAINMENU */
- X "mnymtch.hlp", /* MANYMATCHHELP */
- X "moption.hlp", /* MOPTIONHELP */
- X "moptions.hlp", /* MOPTIONSHELP */
- X "moreflds.hlp", /* MOREFIELDSHELP */
- X "newadd.hlp", /* NEWADDHELP */
- X "otherfmt.hlp", /* OTHERFORMATHELP */
- X "pkentry.hlp", /* PICKENTRYHELP */
- X "pkntmenu.hlp", /* PICKENTRYMENU */
- X "poptmenu.hlp", /* POPTIONMENU */
- X "poptions.hlp", /* POPTIONSHELP */
- X "srchstr.hlp", /* SEARCHSTRINGHELP */
- X "update.hlp", /* UPDATEHELP */
- X "updatmnu.hlp", /* UPDATEMENU */
- X "usrfld.hlp", /* USERFIELDHELP */
- X};
- X
- X
- Xread_rolodex (fd) int fd;
- X
- X{
- X struct stat statdata;
- X long filesize;
- X int i,j,k,start_of_others,warning_given;
- X Ptr_Rolo_Entry newentry;
- X Ptr_Rolo_List newlink,rptr;
- X char *next_field,*next_other;
- X char **other_pointers;
- X int n_entries = 0;
- X
- X /* find out how many bytes are in the file */
- X
- X fstat(fd,&statdata);
- X if ((filesize = statdata.st_size) == 0) {
- X return(0);
- X }
- X
- X /* create an array of characters that big */
- X
- X rolofiledata = rolo_emalloc(filesize);
- X
- X /* read them all in at once for efficiency */
- X
- X#ifdef MSDOS
- X /*
- X * Unlike Unix, MS-DOS compilers make a distinction between text and
- X * binary files. Unfortunately, this means that in text mode, the file
- X * size is reported by the stat call won't necessarily match the value
- X * reported by the read, since there is CR/LF character translation.
- X * So, the best we can hope for here is that a failed read will give a
- X * zero or negative return value...
- X */
- X if ((filesize = read(fd,rolofiledata,filesize)) <= 0) {
- X#else
- X if (filesize != read(fd,rolofiledata,filesize)) {
- X#endif
- X fprintf(stderr,"rolodex read failed\n");
- X exit(-1);
- X }
- X
- X j = 0;
- X
- X /* for each entry in the rolodex file */
- X
- X while (j < filesize) {
- X
- X n_entries++;
- X
- X /* create the link and space for the data entry */
- X
- X newlink = new_link_with_entry();
- X newentry = get_entry(newlink);
- X if (j == 0) {
- X Begin_Rlist = newlink;
- X set_prev_link(newlink,0);
- X set_next_link(newlink,0);
- X }
- X else {
- X set_next_link(End_Rlist,newlink);
- X set_prev_link(newlink,End_Rlist);
- X set_next_link(newlink,0);
- X }
- X End_Rlist = newlink;
- X
- X /* locate each required field in the character array and change */
- X /* the ending line feed to a null. Insert a pointer to the */
- X /* beginning of the field into the data entry */
- X
- X for (i = 0; i < N_BASIC_FIELDS; i++) {
- X next_field = rolofiledata + j;
- X while (rolofiledata[j] != '\n') {
- X j++;
- X }
- X rolofiledata[j] = '\0';
- X j++;
- X set_basic_rolo_field(i,newentry,next_field);
- X }
- X
- X /* the end of an entry is indicated by two adjacent newlines */
- X
- X if (rolofiledata[j] == '\n') {
- X j++;
- X newentry -> other_fields = 0;
- X continue;
- X }
- X
- X /* there must be additional, user-inserted fields. Find out how many. */
- X
- X start_of_others = j;
- X while (1) {
- X while (rolofiledata[j] != '\n') {
- X j++;
- X }
- X incr_n_others(newentry);
- X j++;
- X if (rolofiledata[j] == '\n') {
- X j++;
- X break;
- X }
- X }
- X
- X /* allocate an array of character pointers to hold these fields */
- X
- X other_pointers = (char **)rolo_emalloc(get_n_others(newentry)*sizeof(char *));
- X
- X /* separate each field and insert a pointer to it in the char array */
- X
- X k = start_of_others;
- X for (i = 0; i < get_n_others(newentry); i++) {
- X next_other = rolofiledata + k;
- X while (rolofiledata[k] != '\n') {
- X k++;
- X }
- X rolofiledata[k] = '\0';
- X other_pointers[i] = next_other;
- X k++;
- X }
- X
- X /* insert the pointer to this character array into the data entry */
- X
- X newentry -> other_fields = other_pointers;
- X
- X }
- X
- X /* check that all the entries are in alphabetical order by name */
- X
- X warning_given = 0;
- X rptr = get_next_link(Begin_Rlist);
- X while (rptr != 0) {
- X if (1 == compare_links(get_prev_link(rptr),rptr)) {
- X if (!warning_given) fprintf(stderr,"Warning, rolodex out of order\n");
- X warning_given = 1;
- X reorder_file = 1;
- X }
- X rptr = get_next_link(rptr);
- X }
- X
- X return(n_entries);
- X
- X}
- X
- X
- Xwrite_rolo_list (fp) FILE *fp;
- X
- X/* write the entire in-core rolodex to a file */
- X
- X{
- X
- X Ptr_Rolo_List rptr;
- X Ptr_Rolo_Entry lentry;
- X int j;
- X
- X rptr = Begin_Rlist;
- X
- X while (rptr != 0) {
- X lentry = get_entry(rptr);
- X for (j = 0; j < N_BASIC_FIELDS; j++) {
- X fprintf(fp,"%s\n",get_basic_rolo_field(j,lentry));
- X }
- X for (j = 0; j < get_n_others(lentry); j++) {
- X fprintf(fp,"%s\n",get_other_field(j,lentry));
- X }
- X fprintf(fp,"\n");
- X rptr = get_next_link(rptr);
- X }
- X
- X}
- X
- X
- Xwrite_rolo (fp1,fp2) FILE *fp1; FILE *fp2;
- X
- X{
- X write_rolo_list(fp1);
- X write_rolo_list(fp2);
- X}
- X
- X
- Xdisplay_basic_field (name,value,show,up) char *name; char *value; int show,up;
- X{
- X int i;
- X if ((value == (char *)NULL) || (all_whitespace(value) && !show)) return;
- X printf("%-25s",name);
- X while (*value != '\0') {
- X if (*value == ';') {
- X while (*++value == ' ');
- X putchar('\n');
- X for (i = 0; i < (up ? 28 : 25); i++) putchar(' ');
- X }
- X else {
- X putchar(*value++);
- X }
- X }
- X putchar('\n');
- X}
- X
- X
- Xdisplay_other_field (fieldstring) char *fieldstring;
- X{
- X int already_put_sep = 0;
- X int count = 0;
- X int i;
- X while (*fieldstring != '\0') {
- X if (*fieldstring == ';' && already_put_sep) {
- X while (*++fieldstring == ' ');
- X putchar('\n');
- X for (i = 0; i < 25; i++) putchar(' ');
- X continue;
- X }
- X putchar(*fieldstring);
- X count++;
- X if (*fieldstring == ':' && !already_put_sep) {
- X for (i = count; i < 24; i++) putchar(' ');
- X already_put_sep = 1;
- X }
- X fieldstring++;
- X }
- X putchar('\n');
- X}
- X
- X
- Xsummarize_entry_list (rlist,ss) Ptr_Rolo_List rlist; char *ss;
- X
- X/* print out the Name field for each entry that is tagged as matched */
- X/* and number each entry. */
- X
- X{
- X int count = 1;
- X clear_the_screen();
- X printf("Entries that match '%s' :\n\n",ss);
- X while (rlist != 0) {
- X if (get_matched(rlist)) {
- X printf (
- X "%d. \t%s\n",
- X count++,
- X get_basic_rolo_field((int) R_NAME,get_entry(rlist))
- X );
- X }
- X rlist = get_next_link(rlist);
- X }
- X putchar('\n');
- X}
- X
- X
- Xdisplay_field_names ()
- X
- X/* display and number each standard field name. */
- X
- X{
- X int j;
- X char *name;
- X clear_the_screen();
- X for (j = 0; j < N_BASIC_FIELDS - 1; j++) {
- X name = Field_Names[j];
- X printf("%d. ",j+1);
- X while (*name != ':') putchar(*name++);
- X putchar('\n');
- X }
- X printf("%d. ",N_BASIC_FIELDS);
- X printf("A user created item name\n\n");
- X}
- X
- Xdisplay_entry (lentry) Ptr_Rolo_Entry lentry;
- X{
- X int j,n_others;
- X char *string;
- X
- X clear_the_screen();
- X
- X /* display the standard fields other than Date Updated */
- X
- X for (j = 0; j < N_BASIC_FIELDS - 1; j++) {
- X string = get_basic_rolo_field(j,lentry);
- X display_basic_field(Field_Names[j],string,0,0);
- X }
- X
- X /* display any additional fields the user has defined for this entry */
- X
- X n_others = get_n_others(lentry);
- X for (j = 0; j < n_others; j++) {
- X string = get_other_field(j,lentry);
- X display_other_field(string);
- X }
- X
- X /* display the Date Updated field */
- X
- X j = N_BASIC_FIELDS - 1;
- X display_basic_field(Field_Names[j],get_basic_rolo_field(j,lentry),0,0);
- X fprintf(stdout,"\n");
- X
- X}
- X
- X
- Xdisplay_entry_for_update (lentry) Ptr_Rolo_Entry lentry;
- X
- X/* same as display_entry, except each item is numbered and the Date Updated */
- X/* item is not displayed */
- X
- X{
- X int j,n_others;
- X char *string;
- X int count = 1;
- X
- X clear_the_screen();
- X
- X for (j = 0; j < N_BASIC_FIELDS - 1; j++) {
- X string = get_basic_rolo_field(j,lentry);
- X printf("%d. ",count++);
- X display_basic_field(Field_Names[j],string,1,1);
- X }
- X
- X n_others = get_n_others(lentry);
- X for (j = 0; j < n_others; j++) {
- X string = get_other_field(j,lentry);
- X printf("%d. ",count++);
- X display_other_field(string);
- X }
- X
- X printf("%d. Add a new user defined field\n",count);
- X
- X fprintf(stdout,"\n");
- X
- X}
- X
- X
- Xint cathelpfile (fileidx,helptopic,clear)
- X
- X int fileidx;
- X char *helptopic;
- X int clear;
- X
- X{
- X register char *filepath;
- X FILE *fp;
- X char buffer[MAXLINELEN];
- X
- X if(fileidx > LAST_HELP) {
- X fprintf(stderr,
- X "INTERNAL ERROR: Error file index, max: %d, requested: %d\n",
- X LAST_HELP,fileidx);
- X return;
- X }else
- X filepath = libdir(hlpfiles[fileidx]);
- X
- X if (clear) clear_the_screen();
- X if (NULL == (fp = fopen(filepath,"r"))) {
- X if (helptopic) {
- X printf("No help available on %s, sorry.\n\n",helptopic);
- X }
- X else {
- X fprintf(stderr,"Fatal error, can't open %s\n",filepath);
- X exit(-1);
- X }
- X return;
- X }
- X while (NULL != fgets(buffer,MAXLINELEN,fp)) printf("%s",buffer);
- X printf("\n");
- X fclose(fp);
- X return;
- X}
- X
- X
- Xany_char_to_continue ()
- X{
- X char buffer[80];
- X printf("RETURN to continue: ");
- X fgets(buffer,80,stdin);
- X return;
- X}
- END_OF_FILE
- if test 10740 -ne `wc -c <'./io.c'`; then
- echo shar: \"'./io.c'\" unpacked with wrong size!
- fi
- # end of './io.c'
- fi
- if test -f './operatns.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./operatns.c'\"
- else
- echo shar: Extracting \"'./operatns.c'\" \(9950 characters\)
- sed "s/^X//" >'./operatns.c' <<'END_OF_FILE'
- X/* operatns.c */
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#ifdef TMC
- X#include <ctools.h>
- X#else
- X#include "ctools.h"
- X#endif
- X#include "args.h"
- X#include "menu.h"
- X#include "mem.h"
- X
- X#include "rolofilz.h"
- X#include "rolodefs.h"
- X#include "datadef.h"
- X#include "choices.h"
- X
- X#define index strchr
- Xchar *index();
- X
- Xextern char *ctime();
- X
- XPtr_Rolo_List create_entry (basicdata,otherdata) char **basicdata, **otherdata;
- X{
- X Ptr_Rolo_List newlink;
- X Ptr_Rolo_Entry newentry;
- X int i,j;
- X newlink = new_link_with_entry();
- X newentry = get_entry(newlink);
- X for (j = 0; j < N_BASIC_FIELDS; j++) {
- X set_basic_rolo_field(j,newentry,basicdata[j]);
- X }
- X j = 0;
- X while (otherdata[j] != 0) j++;
- X set_n_others(newentry,j);
- X if (j > 0) {
- X newentry -> other_fields = (char **) rolo_emalloc(j*sizeof(char *));
- X for (i = 0; i < j; i++) {
- X set_other_field(i,newentry,otherdata[i]);
- X }
- X }
- X else newentry -> other_fields = 0;
- X return(newlink);
- X}
- X
- X
- Xother_fields ()
- X{
- X int rval;
- X rval = rolo_menu_yes_no (
- X "Additional fields? ",DEFAULT_NO,1,
- X MOREFIELDSHELP, "additional fields"
- X );
- X return(rval == MENU_YES);
- X}
- X
- X
- Xadd_the_entry ()
- X{
- X return(MENU_YES == rolo_menu_yes_no (
- X "Add new entry to rolodex? ",DEFAULT_YES,1,
- X NEWADDHELP, "adding newly entered entry"
- X ));
- X}
- X
- X
- Xrolo_add ()
- X
- X{
- X int i,j,k,rval,menuval;
- X char *response;
- X char *basicdata[N_BASIC_FIELDS], *otherdata[100];
- X Ptr_Rolo_List rlink;
- X
- X if(read_only)
- X {
- X printf("Readonly mode: cannot add entries.\n");
- X sleep(2);
- X return(1);
- X }
- X
- X for (j = 0; j < 100; j++) otherdata[j] = (char *)NULL;
- X for (j = 0; j < N_BASIC_FIELDS; j++) basicdata[j] = (char *)NULL;
- X cathelpfile(ADDINFO,(char *)NULL,1);
- X
- X /* 'k' and 'kludge' are are kludge to allow us to back up from entering */
- X /* user defined fields to go an correct wrong basic field information. */
- X
- X k = 0;
- X
- X kludge :
- X
- X for (j = k; j < N_BASIC_FIELDS - 1; j++) {
- X
- X redo :
- X
- X rval = menu_match (
- X &menuval,&response,
- X Field_Names[j],
- X 0,0,0,1,5,
- X "\\",A_ABORT_ADD,
- X "^",A_BACKUP,
- X "!",A_FILL_IN_REST,
- X "?",A_HELP,
- X "",A_NO_DATA
- X );
- X
- X switch (rval) {
- X
- X case MENU_NO_MATCH :
- X basicdata[j] = copystr(response);
- X if (j == 0 && strlen(basicdata[j]) == 0) {
- X printf("Each entry must have a name!\n\n");
- X sleep(2);
- X goto redo;
- X }
- X break;
- X
- X case MENU_MATCH :
- X switch (menuval) {
- X case A_BACKUP :
- X if (j == 0) return(0);
- X j--;
- X goto redo;
- X /* break; */
- X case A_ABORT_ADD :
- X return(0);
- X /* break; */
- X case A_FILL_IN_REST :
- X if (j == 0) {
- X fprintf(stderr,"You must enter at least a name...\n\n");
- X sleep(2);
- X goto redo;
- X }
- X goto add_entry;
- X /* break; */
- X case A_HELP :
- X cathelpfile(ADDHELP,"adding entries",1);
- X any_char_to_continue();
- X clear_the_screen();
- X cathelpfile(ADDINFO,(char *)NULL,0);
- X for (i = 0; i < j; i++) {
- X printf("%s%s\n",Field_Names[i],basicdata[i]);
- X }
- X goto redo;
- X /* break; */
- X case A_NO_DATA :
- X if (j == 0) {
- X fprintf(stderr,"You must enter at least a name...\n\n");
- X sleep(2);
- X goto redo;
- X }
- X
- X if (basicdata[j] != (char *)NULL)
- X basicdata[j][0] = '\0';
- X else
- X basicdata[j] = "";
- X break;
- X default :
- X fprintf(stderr,"Impossible rval from rolo_add menu_match\n\n");
- X save_and_exit(-1);
- X break;
- X }
- X break;
- X
- X case MENU_EOF :
- X user_eof();
- X break;
- X
- X case MENU_ERROR :
- X case MENU_AMBIGUOUS :
- X default :
- X fprintf(stderr,"Impossible return from rolo_add menu_match\n");
- X save_and_exit(-1);
- X break;
- X
- X }
- X
- X }
- X
- X if (other_fields()) {
- X for (j = 0; j < 100; j++) {
- X redo_other :
- X rval = menu_match (
- X &menuval,&response,
- X "Enter <name>: <data> (type RETURN to quit) : ",
- X 0,0,0,0,5,
- X "\\",O_ABORT,
- X "?",O_HELP,
- X "Help",O_HELP,
- X "^",O_BACKUP,
- X "",O_DONE_OTHERS
- X );
- X switch (rval) {
- X case MENU_MATCH :
- X switch (menuval) {
- X case O_DONE_OTHERS :
- X goto add_entry;
- X /* break; */
- X case O_BACKUP :
- X if (j == 0) {
- X k = N_BASIC_FIELDS - 2;
- X goto kludge;
- X }
- X else {
- X j--;
- X printf("Deleting %s\n",otherdata[j]);
- X goto redo_other;
- X }
- X /* break; */
- X case O_ABORT :
- X return(0);
- X /* break; */
- X case O_HELP :
- X cathelpfile(OTHERFORMATHELP,"user-item format",1);
- X any_char_to_continue();
- X goto redo_other;
- X }
- X break;
- X case MENU_NO_MATCH :
- X if ((index(response,':') == (char *)NULL) ||
- X (*response == ':')) {
- X printf("No field name provided -- separate with a ':'.\n");
- X goto redo_other;
- X }
- X otherdata[j] = copystr(response);
- X break;
- X case MENU_EOF :
- X user_eof();
- X break;
- X case MENU_AMBIGUOUS :
- X case MENU_ERROR :
- X default :
- X fprintf(stderr,"Impossible rval from add_other menu_match\n");
- X save_and_exit(-1);
- X }
- X }
- X }
- X
- X add_entry :
- X
- X basicdata[N_BASIC_FIELDS - 1] = timestring();
- X
- X rlink = create_entry(basicdata,otherdata);
- X clear_the_screen();
- X display_entry(get_entry(rlink));
- X if (add_the_entry()) {
- X printf (
- X "Adding entry for %s to rolodex\n",
- X get_basic_rolo_field((int) R_NAME,get_entry(rlink))
- X );
- X rolo_insert(rlink,compare_links);
- X changed = 1;
- X sleep(2);
- X }
- X else {
- X return(0);
- X }
- X return(0); /* Should never hit this... */
- X}
- X
- X
- Xentry_action (rlink) Ptr_Rolo_List rlink;
- X
- X{
- X static entry_menu_displayed = 0;
- X int rval,menuval;
- X char *response;
- X
- X if (!entry_menu_displayed) cathelpfile(ENTRYMENU,(char *)NULL,0);
- X#ifdef NEVERDEF
- X entry_menu_displayed = 1; /* This may be turned off to provide verbose help */
- X#endif
- X
- X redo :
- X
- X rval = menu_match (
- X &menuval, &response,
- X "Action (? for help) : ",
- X 0,1,1,1,7,
- X "\\",E_ABORT,
- X "?",E_HELP,
- X "",E_CONTINUE,
- X "-",E_DELETE,
- X "+",E_UPDATE,
- X "<",E_PREV,
- X "%",E_SCAN
- X );
- X
- X if (rval != MENU_MATCH) {
- X if (rval == MENU_EOF) user_eof();
- X fprintf(stderr,"Impossible return from entry_action menu_match\n");
- X save_and_exit(-1);
- X }
- X
- X switch (menuval) {
- X case E_ABORT :
- X case E_CONTINUE :
- X case E_PREV :
- X break;
- X case E_SCAN :
- X rolo_peruse_mode(get_next_link(rlink));
- X break;
- X case E_UPDATE :
- X rolo_update_mode(rlink);
- X break;
- X case E_DELETE :
- X if(!rolo_delete(rlink))
- X printf("Entry deleted\n");
- X sleep(1);
- X changed = 1;
- X break;
- X case E_HELP :
- X cathelpfile (
- X (in_search_mode ? ESEARCHHELP : ESCANHELP),
- X "entry actions",
- X 1
- X );
- X any_char_to_continue();
- X clear_the_screen();
- X display_entry(get_entry(rlink));
- X goto redo;
- X /* break; */
- X default :
- X fprintf(stderr,"Impossible menuval in entry_action\n");
- X save_and_exit(-1);
- X }
- X
- X return(menuval);
- X
- X}
- X
- X
- Xdisplay_list_of_entries (rlist) Ptr_Rolo_List rlist;
- X
- X{
- X Ptr_Rolo_List old,hold;
- X
- X if(rlist != 0)
- X hold = get_next_link(rlist); /* In case of change */
- X
- X while (rlist != 0) {
- X
- X if (!get_matched(rlist)) goto next;
- X
- X loop :
- X
- X display_entry(get_entry(rlist));
- X
- X switch (entry_action(rlist)) {
- X case E_CONTINUE :
- X break;
- X case E_ABORT :
- X return(0);
- X /* break; */
- X case E_PREV :
- X old = rlist;
- X find_prev_match :
- X if (get_prev_link(rlist) == 0) {
- X rlist = old;
- X printf("No previous entry in scan list\n");
- X sleep(2);
- X }
- X else {
- X rlist = get_prev_link(rlist);
- X if (!get_matched(rlist)) goto find_prev_match;
- X }
- X goto loop;
- X /* break; */
- X case E_UPDATE :
- X if(name_changed)
- X {
- X printf("Continuing scan at next entry in scan list before change...\n");
- X sleep(1);
- X rlist = hold;
- X
- X break;
- X }
- X /* Deliberate fall-thru */
- X default :
- X printf("Displaying next entry in scan list...\n");
- X sleep(1);
- X break;
- X }
- X
- X next :
- X
- X if(!name_changed)
- X rlist = get_next_link(rlist);
- X else
- X name_changed = 0;
- X
- X if(rlist != 0)
- X hold = get_next_link(rlist); /* In case of change */
- X
- X }
- X
- X printf("No further entries to scan...\n");
- X sleep(2);
- X return(0);
- X}
- X
- X
- Xrolo_peruse_mode (first_rlink) Ptr_Rolo_List first_rlink;
- X
- X{
- X Ptr_Rolo_List rlist = first_rlink;
- X if (0 == Begin_Rlist) {
- X fprintf(stderr,"No further entries in rolodex...\n");
- X sleep(2);
- X return(0);
- X }
- X while (rlist != 0) {
- X set_matched(rlist);
- X rlist = get_next_link(rlist);
- X }
- X display_list_of_entries(first_rlink);
- X rlist = first_rlink;
- X while (rlist != 0) {
- X unset_matched(rlist);
- X rlist = get_next_link(rlist);
- X }
- X
- X return(0);
- X}
- END_OF_FILE
- if test 9950 -ne `wc -c <'./operatns.c'`; then
- echo shar: \"'./operatns.c'\" unpacked with wrong size!
- fi
- # end of './operatns.c'
- fi
- if test -f './rolo.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./rolo.c'\"
- else
- echo shar: Extracting \"'./rolo.c'\" \(18313 characters\)
- sed "s/^X//" >'./rolo.c' <<'END_OF_FILE'
- X/* rolo.c */
- X#ifdef UNIX
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <pwd.h>
- X#include <string.h>
- X#ifdef BSD
- X#include <sys/file.h>
- X#else
- X#include <fcntl.h>
- X#endif
- X#endif
- X
- X#ifdef VMS
- X#include <types.h>
- X#include <file.h>
- X#include <stat.h>
- X#include <string.h>
- X#endif
- X
- X#ifdef MSDOS
- X#include <fcntl.h>
- X# ifdef MSC
- X# include <sys ypes.h>
- X# endif /* MSC */
- X#include <sys/stat.h>
- X#include <errno.h>
- X#include <string.h>
- X#endif
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X/* #include <sgtty.h> */
- X#include <signal.h>
- X
- X
- X#ifdef TMC
- X#include <ctools.h>
- X#else
- X#include "ctools.h"
- X#endif
- X#include "args.h"
- X#include "menu.h"
- X#include "mem.h"
- X
- X#include "rolofilz.h"
- X#include "rolodefs.h"
- X#include "datadef.h"
- X
- X#ifndef BSD
- X/* BSD Unix gives us these values but AT&T Unix, VMS and MSDOS don't */
- X/* Used with 'access(2)' syscall */
- X#define R_OK 04
- X#define F_OK 00
- X#define W_OK 02
- X#endif
- X
- X#ifdef UNIX
- X#define DEF_PERM 0600 /* Default permissions: All, for owner only */
- X#endif
- X
- X#ifdef VMS
- X#define DEF_PERM 0600 /* Default permissions: All, for owner only */
- X#endif
- X
- X#ifdef MSDOS
- X#define DEF_PERM (S_IREAD | S_IWRITE) /* Default permissions: All */
- X#endif
- X
- X#define MAX_LINES 60 /* Max number of lines/page */
- X
- Xstatic struct stat stat_buf;
- X
- Xstatic char rolodir[DIRPATHLEN]; /* directory where rolo data is */
- Xstatic char filebuf[DIRPATHLEN]; /* stores result of homedir() */
- X
- Xint changed = 0;
- Xint name_changed = 0;
- Xint reorder_file = 0;
- Xint rololocked = 0;
- Xint in_search_mode = 0;
- Xint read_only = 0;
- X
- Xchar *rolo_emalloc (size) int size;
- X
- X/* error handling memory allocator */
- X
- X{
- X char *rval;
- X char *malloc();
- X if (0 == (rval = malloc((unsigned)size))) {
- X fprintf(stderr,"Fatal error: out of memory\n");
- X save_and_exit(-1);
- X }
- X return(rval);
- X}
- X
- X
- Xchar *copystr (s) char *s;
- X
- X/* memory allocating string copy routine */
- X
- X
- X{
- X char *copy;
- X if (s == 0) return(0);
- X copy = rolo_emalloc(strlen(s) + 1);
- X strcpy(copy,s);
- X return(copy);
- X}
- X
- X
- Xchar *timestring ()
- X
- X/* returns a string timestamp */
- X
- X{
- X char *s;
- X long timeval;
- X long time();
- X
- X time(&timeval);
- X s = ctime(&timeval);
- X s[strlen(s) - 1] = '\0';
- X return(copystr(s));
- X}
- X
- X
- Xuser_interrupt ()
- X
- X/* if the user hits C-C (we assume he does it deliberately) */
- X
- X{
- X#ifdef VMS
- X delete(homedir(ROLOLOCK));
- X delete(homedir(ROLOTEMP));
- X#else
- X unlink(homedir(ROLOLOCK));
- X unlink(homedir(ROLOTEMP));
- X#endif
- X fprintf(stderr,"\nAborting rolodex, no changes since last save recorded\n");
- X exit(-1);
- X}
- X
- X
- Xuser_eof ()
- X
- X/* if the user hits C-D */
- X
- X{
- X#ifdef VMS
- X delete(homedir(ROLOLOCK));
- X#else
- X unlink(homedir(ROLOLOCK));
- X#endif
- X fprintf(stderr,"\nUnexpected EOF on terminal. Saving rolodex and exiting\n");
- X save_and_exit(-1);
- X}
- X
- X
- Xroloexit (rval) int rval;
- X{
- X /* In case it hasn't been cleaned up, also clobber ROLOTEMP. */
- X clear_the_screen();
- X if (rololocked)
- X#ifdef VMS
- X delete(homedir(ROLOTEMP));
- X delete(homedir(ROLOLOCK));
- X exit(rval==0?1:rval);
- X#else
- X unlink(homedir(ROLOTEMP));
- X unlink(homedir(ROLOLOCK));
- X exit(rval);
- X#endif
- X}
- X
- X
- Xsave_to_disk ()
- X
- X/* move the old rolodex to a backup, and write out the new rolodex and */
- X/* a copy of the new rolodex (just for safety) */
- X
- X{
- X FILE *tempfp,*copyfp;
- X char *strcpy();
- X char d1[DIRPATHLEN], d2[DIRPATHLEN];
- X
- X#ifdef VMS
- X /*
- X * Since VMS keeps versions of files around, clobber any that are still
- X * hanging around. If appropriate access permissions aren't granted,
- X * well, they'll just have to purge their directory...
- X */
- X delete(homedir(ROLOTEMP)); /* There will be a copy of this from earlier */
- X
- X if(!access(homedir(ROLOCOPY),R_OK))
- X if(!access(homedir(ROLOCOPY),W_OK)) /* Implies delete permission */
- X delete(homedir(ROLOCOPY));
- X#endif
- X tempfp = fopen(homedir(ROLOTEMP),"w");
- X if(tempfp == (FILE *)NULL)
- X perror(ROLOTEMP);
- X
- X copyfp = fopen(homedir(ROLOCOPY),"w");
- X if(copyfp == (FILE *)NULL)
- X perror(ROLOCOPY);
- X
- X if (tempfp == (FILE *)NULL || copyfp == (FILE *)NULL) {
- X fprintf(stderr,"Unable to write rolodex...\n");
- X fprintf(stderr,"Any changes made have not been recorded\n");
- X roloexit(-1);
- X }
- X
- X /*
- X * Be sure to set proper permissions on the temp,copy files *before* putting
- X * data in them...
- X */
- X#ifndef MSDOS
- X if(chmod(homedir(ROLOTEMP),(int)stat_buf.st_mode))
- X fprintf(stderr,"WARNING: Couldn't set permissions on %s\n",
- X homedir(ROLOTEMP));
- X
- X if(chmod(homedir(ROLOCOPY),(int)stat_buf.st_mode))
- X fprintf(stderr,"WARNING: Couldn't set permissions on %s\n",
- X homedir(ROLOCOPY));
- X#endif /* MSDOS */
- X
- X write_rolo(tempfp,copyfp);
- X
- X fclose(tempfp);
- X fclose(copyfp);
- X
- X#ifdef UNIX
- X unlink(strcpy(d1,homedir(ROLOBAK)));
- X link(strcpy(d1,homedir(ROLODATA)),strcpy(d2,homedir(ROLOBAK)));
- X unlink(strcpy(d1,homedir(ROLODATA)));
- X
- X if(link(strcpy(d1,homedir(ROLOTEMP)),strcpy(d2,homedir(ROLODATA))))
- X {
- X fprintf(stderr,"Link failed. Revised rolodex is in %s\n",ROLOCOPY);
- X roloexit(-1);
- X }else
- X {
- X unlink(strcpy(d1,homedir(ROLOTEMP)));
- X unlink(strcpy(d1,homedir(ROLOCOPY)));
- X }
- X#endif
- X
- X#ifdef VMS
- X delete(homedir(ROLOBAK));
- X
- X if ((rename(strcpy(d1,homedir(ROLODATA)),strcpy(d2,homedir(ROLOBAK))) != 1) ||
- X (rename(strcpy(d1,homedir(ROLOTEMP)),strcpy(d2,homedir(ROLODATA)))) != 1) {
- X fprintf(stderr,"Rename failed. Revised rolodex is in %s\n",ROLOCOPY);
- X roloexit(-1);
- X }else
- X delete(homedir(ROLOCOPY)); /* Don't really need this anymore */
- X#endif
- X
- X#ifdef MSDOS
- X unlink(homedir(ROLOBAK));
- X
- X if (rename(strcpy(d1,homedir(ROLODATA)),strcpy(d2,homedir(ROLOBAK))) ||
- X rename(strcpy(d1,homedir(ROLOTEMP)),strcpy(d2,homedir(ROLODATA)))) {
- X fprintf(stderr,"Rename failed. Revised rolodex is in %s\n",ROLOCOPY);
- X perror(homedir(ROLODATA));
- X perror(homedir(ROLOBAK));
- X perror(homedir(ROLOTEMP));
- X roloexit(-1);
- X }else
- X unlink(homedir(ROLOCOPY)); /* Don't really need this anymore */
- X#endif
- X
- X printf("Rolodex saved\n");
- X
- X sleep(1);
- X changed = 0;
- X name_changed = 0;
- X}
- X
- X
- Xsave_and_exit (rval) int rval;
- X{
- X if (changed)
- X save_to_disk();
- X else
- X#ifdef VMS
- X delete(homedir(ROLOTEMP));
- X#endif
- X#ifdef UNIX
- X unlink(homedir(ROLOTEMP));
- X#endif
- X#ifdef MSDOS
- X unlink(homedir(ROLOTEMP));
- X#endif
- X
- X roloexit(rval);
- X}
- X
- X#ifdef UNIX
- Xextern struct passwd *getpwnam();
- X
- Xchar *home_directory (name) char *name;
- X{
- X struct passwd *pwentry;
- X if (0 == (pwentry = getpwnam(name))) return("");
- X return(pwentry -> pw_dir);
- X}
- X#endif
- X
- X#ifdef VMS
- X/*
- X * This routine should never be called in VMS.
- X */
- Xchar *home_directory(name) char *name;
- X{
- X fprintf(stderr,"INTERNAL ERROR: Called home_directory under VMS.\n");
- X exit(0);
- X}
- X#endif
- X
- X#ifdef MSDOS
- X/*
- X * This is rather simplistic. For drives A through C, try to find a directory
- X * named 'name' under the root. If not found on any of the drives, then
- X * simply return the root directory of the current drive.
- X */
- Xchar *home_directory (name) char *name;
- X{
- X char *drvspec = "A:\\";
- X
- X static char dirbuff[128];
- X int fid;
- X
- X for(;*drvspec <= 'C';(*drvspec)++)
- X {
- X strcpy(dirbuff,drvspec);
- X strcat(dirbuff,name);
- X
- X if((fid = open(dirbuff,O_RDONLY)) >= 0)
- X {
- X close(fid);
- X return(dirbuff);
- X }else
- X if(errno != ENOENT && errno != ENODEV)
- X return(dirbuff);
- X }
- X
- X return("/");
- X}
- X#endif
- X
- Xchar *homedir (filename) char *filename;
- X
- X/* e.g., given "rolodex.dat", create "/u/massar/rolodex.dat" */
- X/* rolodir generally the user's home directory but could be someone else's */
- X/* home directory if the -u option is used. */
- X
- X{
- X#ifdef UNIX
- X nbuffconcat(filebuf,3,rolodir,"/",filename);
- X#endif
- X
- X#ifdef MSDOS
- X nbuffconcat(filebuf,3,rolodir,"\\",filename);
- X#endif
- X
- X#ifdef VMS
- X nbuffconcat(filebuf,2,rolodir,filename);
- X#endif
- X
- X return(filebuf);
- X}
- X
- X
- Xchar *libdir (filename) char *filename;
- X
- X/* return a full pathname into the rolodex library directory */
- X/* the string must be copied if it is to be saved! */
- X
- X{
- X#ifdef UNIX
- X nbuffconcat(filebuf,3,ROLOLIB,"/",filename);
- X#endif
- X
- X#ifdef MSDOS
- X /*
- X * If there's no drive specifier in ROLOLIB, then prepend the current
- X * drive.
- X */
- X char *curdir;
- X char *getcwd();
- X
- X curdir = ROLOLIB;
- X
- X if(curdir[2] != ':')
- X {
- X curdir = getcwd((char *)NULL,128);
- X curdir[3] = '\0';
- X nbuffconcat(filebuf,4,curdir,ROLOLIB,"\\",filename);
- X (void)free(curdir);
- X }else
- X nbuffconcat(filebuf,3,ROLOLIB,"\\",filename);
- X#endif
- X
- X#ifdef VMS
- X nbuffconcat(filebuf,2,ROLOLIB,filename);
- X#endif
- X
- X
- X return(filebuf);
- X}
- X
- X
- Xrolo_only_to_read ()
- X{
- X return((option_present(READONLYFLAG) << 1) |
- X (option_present(SUMMARYFLAG) || n_non_option_args()));
- X}
- X
- X
- Xlocked_action ()
- X{
- X if (option_present(OTHERUSERFLAG)) {
- X fprintf(stderr,"Someone else is modifying that rolodex, sorry\n");
- X exit(-1);
- X }
- X else {
- X cathelpfile(LOCKINFO,"locked rolodex",0);
- X exit(-1);
- X }
- X}
- X
- X
- Xpretty_print()
- X{
- X int elt_lines, index, tmp_line_cnt;
- X int line_cnt = 0;
- X char *tmpptr;
- X char *strchr();
- X FILE *lstfp;
- X Ptr_Rolo_List rptr;
- X Ptr_Rolo_Entry lentry;
- X
- X clear_the_screen();
- X
- X fputs("\nPretty printing the Rolodex...\n",stdout);
- X fprintf(stdout,"Print the file %-30s\n", homedir(ROLOPRINT));
- X
- X lstfp = fopen(homedir(ROLOPRINT),"w");
- X if(lstfp == (FILE *)NULL) {
- X perror(homedir(ROLOPRINT));
- X return;
- X }
- X
- X rptr = Begin_Rlist;
- X if(rptr == 0) {
- X fputs("\n\nNo entries to print...\n",stderr);
- X return;
- X }
- X
- X while (rptr != 0) {
- X lentry = get_entry(rptr);
- X
- X /* Find the number of lines this entry requires to print */
- X for(elt_lines = 0, index = 0; index < N_BASIC_FIELDS; index++) {
- X tmpptr = lentry->basicfields[index];
- X elt_lines++; /* Even one for an empty line */
- X
- X while((tmpptr = strchr(tmpptr,';')) != (char *)NULL) {
- X elt_lines++;
- X tmpptr++;
- X }
- X }
- X if(lentry->n_others) {
- X for(index=0; index < lentry->n_others; index++) {
- X elt_lines++; /* As above, even if the entry is empty... */
- X tmpptr = lentry->other_fields[index];
- X
- X while((tmpptr = strchr(tmpptr,';')) != (char *)NULL) {
- X elt_lines++;
- X tmpptr++;
- X }
- X }
- X }
- X
- X /*
- X * Check to see if there is enough room on the current page
- X * to print this entry... Otherwise advance to the top of the
- X * next page
- X */
- X tmp_line_cnt = line_cnt + elt_lines;
- X if(tmp_line_cnt > MAX_LINES) {
- X fputc('\f',lstfp);
- X line_cnt = 0;
- X }
- X
- X /*
- X * We can now start the printing of the actual entry
- X */
- X fputs("Name: ",lstfp);
- X prt_dump(get_basic_rolo_field((int)R_NAME,lentry),lstfp,20);
- X fputs("Home address: ",lstfp);
- X prt_dump(get_basic_rolo_field((int)R_HOME_ADDRESS,lentry),lstfp,20);
- X fputs("Home phone: ",lstfp);
- X prt_dump(get_basic_rolo_field((int)R_HOME_PHONE,lentry),lstfp,20);
- X fputs("Company: ",lstfp);
- X prt_dump(get_basic_rolo_field((int)R_COMPANY,lentry),lstfp,20);
- X fputs("Work address: ",lstfp);
- X prt_dump(get_basic_rolo_field((int)R_WORK_ADDRESS,lentry),lstfp,20);
- X fputs("Work phone: ",lstfp);
- X prt_dump(get_basic_rolo_field((int)R_WORK_PHONE,lentry),lstfp,20);
- X fputs("Remarks: ",lstfp);
- X prt_dump(get_basic_rolo_field((int)R_REMARKS,lentry),lstfp,20);
- X
- X /* Now print any user defined fields */
- X if(lentry->n_others) {
- X fputs("*** User defined fields ***\n",lstfp);
- X line_cnt++;
- X for(index = 0;index < lentry->n_others; index++)
- X fprintf(lstfp,"%-30s\n",get_other_field(index,lentry));
- X }
- X
- X /* Print the date this entry was last updated */
- X fputs(" LAST UPDATED: ",lstfp);
- X prt_dump(get_basic_rolo_field((int)R_UPDATED,lentry),lstfp,20);
- X
- X /* Print two(2) blank lines, and increment the line count */
- X fputs("\n\n",lstfp);
- X line_cnt += elt_lines;
- X line_cnt += 2; /* For the two blank lines between entries */
- X rptr = get_next_link(rptr);
- X }
- X fclose(lstfp);
- X}
- X
- Xprt_dump(strptr, stream, offset)
- Xchar *strptr;
- XFILE *stream;
- Xint offset;
- X{
- X int i;
- X
- X if(*strptr == (char)NULL)
- X fputs("<<NONE>>\n",stream);
- X else {
- X for(; *strptr != '\0'; strptr++) {
- X if(*strptr == ';') {
- X fputc('\n',stream);
- X for(i = 0; i < offset; i++)
- X fputc(' ',stream);
- X }
- X else
- X fputc(*strptr,stream);
- X }
- X fputc('\n',stream);
- X }
- X}
- X
- Xmain (argc,argv) int argc; char *argv[];
- X
- X{
- X int fd,in_use,rolofd;
- X Bool not_own_rolodex;
- X char *user = "";
- X FILE *tempfp;
- X
- X clearinit();
- X clear_the_screen();
- X
- X /* parse the options and arguments, if any */
- X
- X switch (get_args(argc,argv,T,T)) {
- X case ARG_ERROR :
- X roloexit(-1);
- X case NO_ARGS :
- X break;
- X case ARGS_PRESENT :
- X if (ALL_LEGAL != legal_options(LEGAL_OPTIONS)) {
- X fprintf(stderr,"illegal option\nusage: %s\n",USAGE);
- X roloexit(-1);
- X }
- X }
- X
- X /* find the directory in which the rolodex file we want to use is */
- X
- X not_own_rolodex = option_present(OTHERUSERFLAG);
- X if (not_own_rolodex) {
- X if (NIL == (user = option_arg(OTHERUSERFLAG,1)) ||
- X n_option_args(OTHERUSERFLAG) != 1) {
- X fprintf(stderr,"Illegal syntax using -u option\nusage: %s\n",USAGE);
- X roloexit(-1);
- X }
- X }
- X#ifndef MSDOS
- X else {
- X if (0 == (user = getenv("HOME"))) {
- X fprintf(stderr,"Cant find your home directory, no HOME\n");
- X roloexit(-1);
- X }
- X }
- X#endif
- X if (not_own_rolodex) {
- X#ifndef MSDOS
- X strcpy(rolodir,user);
- X#else
- X strcpy(rolodir,home_directory(user));
- X#endif
- X if (*rolodir == '\0') {
- X fprintf(stderr,"No user %s is known to the system\n",user);
- X roloexit(-1);
- X }
- X }
- X else strcpy(rolodir,user);
- X
- X /* is the rolodex readable? */
- X
- X if (0 != access(homedir(ROLODATA),R_OK)) {
- X
- X /* No. if it exists and we cant read it, that's an error */
- X
- X if (0 == access(homedir(ROLODATA),F_OK)) {
- X fprintf(stderr,"Cant access rolodex data file to read\n");
- X roloexit(-1);
- X }
- X
- X /* if it doesn't exist, should we create one? */
- X /* Under Unix, only if it's our own. On other systems, it depends.*/
- X
- X#ifdef UNIX
- X if (option_present(OTHERUSERFLAG)) {
- X fprintf(stderr,"No rolodex file belonging to %s found\n",user);
- X roloexit(-1);
- X }
- X#endif
- X /* try to create it, only if its our own */
- X
- X if (-1 == (fd = creat(homedir(ROLODATA),DEF_PERM))) {
- X if(option_present(OTHERUSERFLAG))
- X fprintf(stderr,"couldn't create rolodex in %s\n",homedir(ROLODATA));
- X else
- X fprintf(stderr,"couldn't create rolodex in your home directory\n");
- X
- X roloexit(-1);
- X }
- X
- X else {
- X stat_buf.st_mode = DEF_PERM; /* For later mode set */
- X close(fd);
- X fprintf(stderr,"Creating empty rolodex...\n");
- X }
- X
- X }
- X
- X /* see if someone else is using it */
- X
- X in_use = (0 == access(homedir(ROLOLOCK),F_OK));
- X
- X /* are we going to access the rolodex only for reading? */
- X
- X if (!(read_only = rolo_only_to_read())) {
- X
- X /* No. Make sure no one else has it locked. */
- X
- X if (in_use) {
- X locked_action();
- X }
- X
- X /* create a lock file. Catch interrupts so that we can remove */
- X /* the lock file if the user decides to abort */
- X
- X if (!option_present(NOLOCKFLAG)) {
- X if ((fd = open(homedir(ROLOLOCK),O_EXCL|O_CREAT,00200|00400)) < 0) {
- X fprintf(stderr,"unable to create lock file...\n");
- X#ifdef VMS
- X exit(0);
- X#else
- X exit(1);
- X#endif
- X }
- X rololocked = 1;
- X close(fd);
- X#ifdef MSDOS
- X# ifdef MSC
- X signal(SIGINT,user_interupt);
- X# else
- X ssignal(SIGINT,user_interrupt); /* Very Turbo-ish */
- X# endif /* MSC */
- X#else
- X signal(SIGINT,user_interrupt);
- X#endif
- X }
- X
- X /* open a temporary file for writing changes to make sure we can */
- X /* write into the directory */
- X
- X /* when the rolodex is saved, the old rolodex is moved to */
- X /* a '~' file (on Unix), the temporary is made to be the new rolodex, */
- X /* and a copy of the new rolodex is made */
- X
- X if (NULL == (tempfp = fopen(homedir(ROLOTEMP),"w"))) {
- X fprintf(stderr,"Can't open temporary file to write to\n");
- X roloexit(-1);
- X }
- X fclose(tempfp);
- X
- X }
- X
- X allocate_memory_chunk(CHUNKSIZE);
- X
- X if (NULL == (rolofd = open(homedir(ROLODATA),O_RDONLY))) {
- X fprintf(stderr,"Can't open rolodex data file to read\n");
- X roloexit(-1);
- X }
- X
- X /* Get the current rolodex file's permissions */
- X if(fstat(rolofd,&stat_buf))
- X {
- X fprintf(stderr,"Can't fstat rolodex data file\n");
- X roloexit(-1);
- X }
- X
- X /* read in the rolodex from disk */
- X /* It should never be out of order since it is written to disk ordered */
- X /* but just in case... */
- X
- X if (!(read_only & 1)) printf("Reading in rolodex from %s\n",homedir(ROLODATA));
- X read_rolodex(rolofd);
- X close(rolofd);
- X if (!(read_only & 1)) printf("%d entries listed\n",rlength(Begin_Rlist));
- X if (reorder_file && !read_only) {
- X fprintf(stderr,"Reordering rolodex...\n");
- X rolo_reorder();
- X fprintf(stderr,"Saving reordered rolodex to disk...\n");
- X save_to_disk();
- X }
- X
- X /* the following routines live in 'options.c' */
- X
- X /* -s option. Prints a short listing of people and phone numbers to */
- X /* standard output */
- X
- X if (option_present(SUMMARYFLAG)) {
- X print_short();
- X#ifdef VMS
- X exit(1);
- X#else
- X exit(0);
- X#endif
- X }
- X
- X /* rolo <name1> <name2> ... */
- X /* print out info about people whose names contain any of the arguments */
- X
- X if (n_non_option_args() > 0) {
- X print_people();
- X#ifdef VMS
- X exit(1);
- X#else
- X exit(0);
- X#endif
- X }
- X
- X /* regular rolodex program */
- X
- X interactive_rolo();
- X#ifdef VMS
- X exit(1);
- X#else
- X exit(0);
- X#endif
- X
- X}
- X
- X#ifdef MSC
- Xsleep(sec)
- Xint sec;
- X{
- X register long tloc;
- X long time();
- X
- X tloc = time((long *)NULL);
- X
- X tloc += (long)sec;
- X
- X while(time((long *)NULL) <= tloc);
- X
- X return(0);
- X}
- X#endif
- END_OF_FILE
- if test 18313 -ne `wc -c <'./rolo.c'`; then
- echo shar: \"'./rolo.c'\" unpacked with wrong size!
- fi
- # end of './rolo.c'
- fi
- if test -f './toolsdir/ctools.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./toolsdir/ctools.h'\"
- else
- echo shar: Extracting \"'./toolsdir/ctools.h'\" \(11422 characters\)
- sed "s/^X//" >'./toolsdir/ctools.h' <<'END_OF_FILE'
- X/* -*- Mode: C; Package: (CTOOLS C) -*- */
- X
- X#ifndef Bool
- X#define Bool int
- X#endif
- X
- X#ifndef T
- X#define T 1
- X#endif
- X
- X#ifndef F
- X#define F 0
- X#endif
- X
- X#ifdef VMS
- X#ifndef MAXINT
- X#define MAXINT 2147483647
- X#define MAXINTSTR "2147483647"
- X#endif
- X#endif
- X
- X#ifdef VMS
- X#ifndef MAXINT
- X#define MAXINT 2147483647
- X#define MAXINTSTR "2147483647"
- X#endif
- X#endif
- X
- X#ifndef MAXPATHLEN
- X#define MAXPATHLEN 80
- X#endif
- X
- Xextern char *emalloc();
- X
- X /* int space; */
- X /* space must be greater than 0 */
- X /* Causes executution to halt with a 'Fatal error' message if memory */
- X /* cannot be allocated, otherwise returns pointer to malloc-ed space */
- X
- Xextern char *anewstr();
- X
- X /* char *astring; */
- X /* emalloc's space and copies astring into that space. Returns pointer */
- X /* to new string. */
- X
- X
- Xextern int copy();
- X
- X /* char *dest, *src; int n; */
- X /* copies exactly n bytes. */
- X /* return value undefined. Use only as procedure. */
- X
- Xextern int fill();
- X
- X /* char *addr, ch; int n; */
- X /* copies ch into n consecutive bytes. */
- X /* return value undefined. Use only as procedure. */
- X
- Xextern int to_upper_if_lower();
- X
- X /* char ch; Returns possibly upper-cased value. */
- X
- Xextern int to_lower_if_upper();
- X
- X /* char ch; Returns possibly lower-cased value. */
- X
- Xextern int buffconcat();
- X
- X /* char *buffer, *s1, *s2; */
- X /* s1 and s2 must be null terminated. Buffer must be at least */
- X /* strlen(s1) + strlen(s2) + 1 characters long. Buffer is null */
- X /* terminated upon completion. */
- X
- X /* return value undefined. Use only as procedure. */
- X
- Xextern int nbuffconcat();
- X
- X /* char *buffer; int n; char *s1,*s2,*s3,*s4,*s5,*s6; */
- X /* all the strings must be null terminated. Buffer must be big enough */
- X /* to hold the null terminated result. 0 < n < 7 .. */
- X /* returns -1 if n is out of range, otherwise 0 */
- X
- Xextern int slcompare();
- X
- X /* char *s1; int l1; char *s2; int l2 */
- X /* does not stop if it encounters a null character. */
- X /* returns 0 if equal, -1 if not equal */
- X
- Xextern int slge_compare();
- X
- X /* char *s1; int l1; char *s2; int l2 */
- X /* does not stop if it encounters a null character. */
- X /* returns 0 if equal, -1 if s1 < s2, 1 if s1 > s2 */
- X
- Xextern int nocase_compare();
- X
- X /* char *s1; int l1; char *s2; int l2 */
- X /* does not stop if it encounters a null character. */
- X /* returns 0 if equal, -1 if s1 < s2, 1 if s1 > s2 case independently. */
- X
- Xextern char * strfind();
- X
- X /* char *s1; char *s2; int fast; */
- X /* finds s2 as a substring of s1. s1 and s2 are null terminated. */
- X /* returns 0 if not found, otherwise pointer into s1 to first matching */
- X /* character. */
- X
- X /* WARNING: will access off the end of s1 in the interest of efficiency */
- X /* if 'fast' is non-zero. */
- X
- Xextern char * strncfind();
- X
- X /* char *s1; char *s2; int fast; */
- X /* finds s2 as a substring of s1 case independently. s1 and s2 are */
- X /* null terminated. */
- X /* returns 0 if not found, otherwise pointer into s1 to first matching */
- X /* character. */
- X
- X /* WARNING: will access off the end of s1 in the interest of efficiency */
- X /* if 'fast' is non-zero. */
- X
- Xextern char * strsearch();
- X
- X /* char *s1; int l1; char *s2; int l2 */
- X /* finds s2 as a substring of s1. Does not stop if it encounters a null. */
- X /* returns pointer into s1, otherwise (char *) 0 if search fails */
- X /* case dependent */
- X
- Xextern char * strncsearch();
- X
- X /* char *s1; int l1; char *s2; int l2 */
- X /* finds s2 as a substring of s1. */
- X /* returns pointer into s1, otherwise (char *) 0 if search fails */
- X /* case independent */
- X
- Xextern int remove_excess_blanks();
- X
- X /* char *newstring, *oldstring; */
- X /* newstring must be long enough to hold the result, which may be as */
- X /* long as oldstring. oldstring must be null terminated. */
- X /* an excess blank is any blank before the first non-blank character, */
- X /* any blank after the last non-blank character, and any blank immediately */
- X /* following a blank. */
- X /* returns length of newstring */
- X
- Xextern int yes_or_no_check();
- X
- X /* char *astring; */
- X /* returns 1 for yes, 0 for no, -1 for neither. */
- X /* astring must be one of "YES", "Y", "NO", "N" in any capitalization. */
- X
- X
- X/* These routines return T if every char satisfies a certain condition. */
- X/* These returns all returns T if given a null string. */
- X
- Xextern Bool all_digits();
- Xextern Bool all_whitespace();
- Xextern Bool all_uppercase();
- Xextern Bool all_lowercase();
- Xextern Bool all_alphabetic();
- Xextern Bool all_alphanumeric();
- Xextern Bool all_ascii();
- X
- X
- Xextern int str_to_pos_int();
- X
- X /* char *astring; int low,high; */
- X /* low must be >= 0. */
- X /* returns -1 if *astring is not composed of digits. */
- X /* returns -2 if the integer is out of range. */
- X /* despite its name, 0 can be returned as a legitimate value. */
- X /* treats all digit strings as decimal. */
- X
- X
- Xextern int sreverse();
- X
- X /* char *buffer; char *astring; */
- X /* puts the characters of astring in reverse order into buffer. */
- X /* buffer must be at least as long as astring + 1. */
- X /* buffer is null terminated when done. */
- X /* No return value. Use only as procedure. */
- X
- Xextern char *ip_sreverse();
- X
- X /* char *astring; */
- X /* Returns astring with its characters reversed. */
- X /* reversal is done in place. */
- X
- X
- X
- X#define PATH_MAXPATHLEN 256
- X
- Xchar *temp_path();
- X
- X/*
- X char *dir; char *filename;
- X
- X Returns a pointer to a character string containing the string
- X <dir>/<filename>. The pointer points to a buffer which will may get
- X overwritten if any functions in this package are subsequently called.
- X 0 is returned if the pathname would exceed PATH_MAXPATHLEN-1 chars.
- X*/
- X
- X
- Xchar *perm_path();
- X
- X/*
- X char *dir; char *filename;
- X
- X Same as temp_path, except the pathname string is malloc'ed and is thus
- X permanent unless specifically freed by the user. Further, no limit
- X on the size of the path is made.
- X*/
- X
- X
- Xchar *make_path();
- X
- X/*
- X char *dir; char *filename; char *extension; Bool perm;
- X
- X Creates <dir>/<filename><extension> . The string returned is permanent
- X or not depending on 'perm'. If perm is not true, 0 will be returned if
- X the resulting path exceeds PATH_MAXPATHLEN-1 chars.
- X*/
- X
- X
- Xchar *make_path_numeric_extension();
- X
- X/*
- X char *dir; char *filename; int extension; Bool perm;
- X
- X Same as make_path except that extension is first converted into a
- X string using sprintf.
- X*/
- X
- X
- Xchar *just_filename();
- X
- X/*
- X char *path; Bool new; Bool perm;
- X
- X Given a path of the form /<x>/<y>/<z> returns <z>. If new is not set
- X then a pointer into the original input string is returned. If new is
- X set a copy is returned, either permanent or not depending on perm.
- X*/
- X
- X
- X#define ANSWER_NO 0
- X#define ANSWER_YES 1
- X#define ANSWER_HELP 2
- X#define ANSWER_QUIT 3
- X#define ANSWER_EOF 4
- X
- X#define AT_EOF -1
- X#define TOO_MANY_CHARS -2
- X#define IOERROR -3
- X#define TOO_MANY_LINES -4
- X#define LINE_TOO_LONG -5
- X
- Xextern read_yes_or_no ();
- X
- X /* FILE *iport, *oport; char *prompt; char *helpstring; char *quitstring; */
- X
- X /* prints prompt, then reads from iport until is gets 'Y', 'N', 'YES' or */
- X /* 'NO' (case independently). If helpstring and/or quitstring are not */
- X /* "" or (char *) 0 then if the user types in one of those ANSWER_HELP */
- X /* or ANSWER_QUIT are returned, otherwise ANSWER_NO or ANSWER_YES are */
- X /* eventually returned. */
- X
- X
- Xextern int getline ();
- X
- X /* FILE *iport; char *buffer; int buflen; */
- X
- X /* reads a line into buffer. Does not put the '\n' into buffer. */
- X /* Returns AT_EOF if at end of file when called. If it encounters */
- X /* end of file after reading at least one character, the eof is treated */
- X /* as if it were a newline. Returns TOO_MANY_CHARS if more than */
- X /* buflen - 1 characters are read before encountering a newline. */
- X /* In this case exactly buflen - 1 characters are read. */
- X /* The last character read is always follwed by a '\0'. */
- X /* if successful getline returns the number of characters read exclusive */
- X /* of a terminating newline or eof. */
- X
- X
- Xextern int getlines();
- X
- X /* FILE *fp; int n; char ***ptr_lines; char *linebuf; int maxlinelen; */
- X /* See documentation for getfile below */
- X /* If called, 'n' must have a value 0. */
- X
- Xextern int getfile();
- X
- X /* char *filename; char ***ptr_lines; char *linebuf; int maxlinelen; */
- X
- X /* read in a file as an array of character strings */
- X /* 'maxlinelen+1' is the maximum length a line of the file is allowed */
- X /* to be. 'linebuf' must be at least 'maxlinelen+1' characters long. */
- X /* Returns the number of lines in the file (and therefore the number */
- X /* of entries in *ptr_lines) if successful. Returns IOERROR if it */
- X /* could not open the file to read from. Returns TOO_MANY_CHARS if */
- X /* it encounters a line longer than 'maxlinelen' characters. */
- X
- X /* Space for each line is malloc'ed as it is read in and the text for */
- X /* the jth line is stored in (*ptr_lines)[j] */
- X
- X /* Only works for fairly small files as it recurses its way through the */
- X /* file and does a lot of malloc-ing. Use read_file_into_buffer or */
- X /* ngetfile for large files. */
- X
- Xextern int ngetlines();
- X
- X /* FILE *fp; int n; char ***ptr_lines; char *linebuf; int maxlinelen; */
- X /* Same as getlines, except at most 'n' lines will be read. Returns */
- X /* TOO_MANY_LINES if more than 'n' lines are present. */
- X
- Xextern int ngetfile();
- X
- X /* int n; char *filename; char ***ptr_lines; char *linebuf; int maxlinelen; */
- X /* See ngetlines above. */
- X
- Xextern int read_file_into_buffer();
- X
- X /* char *filename;
- X char ***ptr_lines;
- X int maxlines;
- X char *buffer;
- X int buflen;
- X char *linebuffer;
- X int linebuflen;
- X */
- X
- X /* *ptr_lines should be an array of character string pointers maxlines */
- X /* big. buffer should be an array of characters buflen long. The routine */
- X /* reads lines using getline and stores them into buffer, terminating each */
- X /* with a null. A pointer to the nth line read is stored in *ptr_lines[n] */
- X /* Returns IOERROR if it cannot open the file for reading, TOO_MANY_LINES */
- X /* if more than maxlines were read in, TOO_MANY_CHARS if buffer is */
- X /* filled before end of file is reached, and LINE_TOO_LONG is any line is */
- X /* longer than linebuflen. Returns number of lines read in if successful. */
- X
- Xextern char *efopen();
- X
- X /* char *filename; char *mode */
- X
- X /* Actually returns a (FILE *), so one must cast the return value to this */
- X /* type. It doesn't return a (FILE *) explicitly because then to include */
- X /* this file one would have to include <stdio.h> explicitly before it. */
- X /* The routine simply calls fopen with the same arguments, but prints a */
- X /* reasonable error message and calls exit if the call to fopen fails. */
- X
- X
- Xextern int record_fseek();
- X
- X /* FILE *fp; long rnum; int fromwhere; int rsize; int hdrsize; */
- X
- X /* Assumes a file is divided into fixed length records with a fixed length */
- X /* header (possibly 0 bytes). Performs a fseek which moves to the start */
- X /* of a given record. Record numbers begin with 1. */
- X
- X /* Returns what fseek returns. */
- X
- X /* 'rnum' is either relative or absolute, depending on 'fromwhere' which */
- X /* corresponds to the 'ptrname' argument of fseek. */
- X
- X
- XBool check_string();
- X
- X /* char *str; long minlen; long maxlen; */
- X
- X /* Returns T if str is not 0 and has a length between minlen and maxlen */
- X /* inclusived, otherwise returns F. */
- X
- X
- X#ifndef check_int
- X#define check_int(i,minval,maxval) ((i) >= (minval) && (i) <= (maxval))
- X#endif
- END_OF_FILE
- if test 11422 -ne `wc -c <'./toolsdir/ctools.h'`; then
- echo shar: \"'./toolsdir/ctools.h'\" unpacked with wrong size!
- fi
- # end of './toolsdir/ctools.h'
- fi
- echo shar: End of archive 3 \(of 4\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-